import 'package:flutter/material.dart';
import 'dart:math';
import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../features/training_records/bloc/training_history_bloc.dart';
import '../features/training_records/bloc/training_history_event.dart';
import '../features/training_records/bloc/training_history_state.dart';
import '../features/training_records/model/training_record.dart';

class MakeTenPage extends StatefulWidget {
  @override
  _MakeTenPageState createState() => _MakeTenPageState();
}

class _MakeTenPageState extends State<MakeTenPage> {
  // 游戏网格大小
  final int rows = 6;
  final int cols = 6;

  // 游戏数据
  List<List<int?>> grid = [];
  List<Offset> selectedCells = [];
  List<List<Offset>> lines = [];

  // 游戏状态
  int score = 0;
  int remainingPairs = 0;
  int requiredPairs = 0;
  int secondsElapsed = 0;
  Timer? timer;
  bool isGameOver = false;

  @override
  void initState() {
    super.initState();
    startGame();
  }

  @override
  void dispose() {
    timer?.cancel();
    super.dispose();
  }

  void startGame() {
    // 初始化游戏数据
    grid = List.generate(rows, (_) => List.generate(cols, (_) => null));
    selectedCells = [];
    lines = [];
    score = 0;
    secondsElapsed = 0;
    isGameOver = false;

    // 生成数字对，确保它们的和为10
    List<int> numbers = [];
    // 生成足够的数字对填满10x10网格
    int totalCells = rows * cols;
    this.requiredPairs = totalCells ~/ 2;

    // 重复添加1-9的数字对，直到填满网格
    while (numbers.length < totalCells) {
      for (int i = 1; i <= 9; i++) {
        numbers.add(i);
        numbers.add(10 - i);
        if (numbers.length >= totalCells) break;
      }
    }

    // 随机打乱数字
    numbers.shuffle();
    remainingPairs = numbers.length ~/ 2;

    // 填充网格
    int index = 0;
    for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
        if (index < numbers.length) {
          grid[i][j] = numbers[index++];
        }
      }
    }

    // 启动计时器
    timer?.cancel();
    timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        secondsElapsed++;
      });
    });
  }

  // 检查两点之间是否可以连接（直线或最多两个拐点）
  bool canConnect(int startRow, int startCol, int endRow, int endCol) {
    // 检查两个方向的可能性
    if (canConnectDirectly(startRow, startCol, endRow, endCol) ||
        canConnectDirectly(endRow, endCol, startRow, startCol)) {
      return true;
    }

    // 检查一个拐点的连接
    // 拐点 (startRow, endCol)
    if (grid[startRow][endCol] == null &&
        canConnectDirectly(startRow, startCol, startRow, endCol) &&
        canConnectDirectly(startRow, endCol, endRow, endCol)) {
      return true;
    }

    // 拐点 (endRow, startCol)
    if (grid[endRow][startCol] == null &&
        canConnectDirectly(startRow, startCol, endRow, startCol) &&
        canConnectDirectly(endRow, startCol, endRow, endCol)) {
      return true;
    }

    // 检查两个拐点的连接
    // 类型1: 水平 -> 垂直 -> 水平
    // 路径: (startRow, startCol) -> (startRow, k) -> (endRow, k) -> (endRow, endCol)
    // 角点C1 = (startRow, k), 角点C2 = (endRow, k)
    for (int k = 0; k < cols; k++) {
      // 两个角点必须为空
      if (grid[startRow][k] == null && grid[endRow][k] == null) {
        if (canConnectDirectly(startRow, startCol, startRow, k) && // S to C1
            canConnectDirectly(startRow, k, endRow, k) && // C1 to C2
            canConnectDirectly(endRow, k, endRow, endCol)) {
          // C2 to E
          return true;
        }
      }
    }

    // 类型2: 垂直 -> 水平 -> 垂直
    // 路径: (startRow, startCol) -> (k, startCol) -> (k, endCol) -> (endRow, endCol)
    // 角点C1 = (k, startCol), 角点C2 = (k, endCol)
    for (int k = 0; k < rows; k++) {
      // 两个角点必须为空
      if (grid[k][startCol] == null && grid[k][endCol] == null) {
        if (canConnectDirectly(startRow, startCol, k, startCol) && // S to C1
            canConnectDirectly(k, startCol, k, endCol) && // C1 to C2
            canConnectDirectly(k, endCol, endRow, endCol)) {
          // C2 to E
          return true;
        }
      }
    }

    return false;
  }

  // 检查两点之间是否可以直线连接（中间没有其他数字阻挡）
  bool canConnectDirectly(int startRow, int startCol, int endRow, int endCol) {
    // 如果不在同一行也不在同一列，则不能直线连接
    if (startRow != endRow && startCol != endCol) {
      return false;
    }

    // 检查水平方向
    if (startRow == endRow) {
      int minCol = min(startCol, endCol);
      int maxCol = max(startCol, endCol);

      for (int col = minCol + 1; col < maxCol; col++) {
        if (grid[startRow][col] != null) {
          return false; // 中间有障碍物
        }
      }
      return true;
    }

    // 检查垂直方向
    if (startCol == endCol) {
      int minRow = min(startRow, endRow);
      int maxRow = max(startRow, endRow);

      for (int row = minRow + 1; row < maxRow; row++) {
        if (grid[row][startCol] != null) {
          return false; // 中间有障碍物
        }
      }
      return true;
    }

    return false;
  }

  // 获取连接路径的点
  List<Offset> getConnectionPath(
      int startRow, int startCol, int endRow, int endCol) {
    List<Offset> path = [];
    path.add(Offset(startCol.toDouble(), startRow.toDouble()));

    // 直线连接
    if (canConnectDirectly(startRow, startCol, endRow, endCol)) {
      path.add(Offset(endCol.toDouble(), endRow.toDouble()));
      return path;
    }

    // 一个拐点连接
    // 拐点 (startRow, endCol)
    if (grid[startRow][endCol] == null &&
        canConnectDirectly(startRow, startCol, startRow, endCol) &&
        canConnectDirectly(startRow, endCol, endRow, endCol)) {
      path.add(Offset(endCol.toDouble(), startRow.toDouble()));
      path.add(Offset(endCol.toDouble(), endRow.toDouble()));
      return path;
    }

    // 拐点 (endRow, startCol)
    if (grid[endRow][startCol] == null &&
        canConnectDirectly(startRow, startCol, endRow, startCol) &&
        canConnectDirectly(endRow, startCol, endRow, endCol)) {
      path.add(Offset(startCol.toDouble(), endRow.toDouble()));
      path.add(Offset(endCol.toDouble(), endRow.toDouble()));
      return path;
    }

    // 两个拐点连接
    for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
        if ((i == startRow && j == startCol) || (i == endRow && j == endCol)) {
          continue;
        }

        if (grid[i][j] == null &&
            grid[i][startCol] == null &&
            grid[endRow][j] == null) {
          if (canConnectDirectly(startRow, startCol, i, startCol) &&
              canConnectDirectly(i, startCol, i, j) &&
              canConnectDirectly(i, j, endRow, j) &&
              canConnectDirectly(endRow, j, endRow, endCol)) {
            path.add(Offset(startCol.toDouble(), i.toDouble()));
            path.add(Offset(j.toDouble(), i.toDouble()));
            path.add(Offset(j.toDouble(), endRow.toDouble()));
            path.add(Offset(endCol.toDouble(), endRow.toDouble()));
            return path;
          }
        }
      }
    }

    return path;
  }

  void selectCell(int row, int col) {
    if (isGameOver || grid[row][col] == null) return;

    // 重置已选路径当点击新单元格时
    if (selectedCells.length == 1) {
      lines.clear();
    }

    setState(() {
      if (selectedCells.isEmpty) {
        // 第一次选择
        // print('First click'); // 打印第一次点击
        selectedCells.add(Offset(col.toDouble(), row.toDouble()));
      } else if (selectedCells.length == 1) {
        // 第二次选择
        // print('Second click'); // 打印第二次点击
        final firstCell = selectedCells[0];
        final firstRow = firstCell.dy.toInt();
        final firstCol = firstCell.dx.toInt();

        // 检查是否选择了同一个单元格
        if (row == firstRow && col == firstCol) {
          // print('Clicked the same cell, clearing selection.');
          selectedCells.clear();
          return;
        }

        // 检查两个数字之和是否为10
        final firstValue = grid[firstRow][firstCol]!;
        final secondValue = grid[row][col]!;
        // print(
        //     'Checking match: $firstValue + $secondValue = ${firstValue + secondValue}'); // 打印检查的值

        // 添加第二个选择的单元格
        selectedCells.add(Offset(col.toDouble(), row.toDouble()));

        bool connectable = canConnect(firstRow, firstCol, row, col);
        // print('Checking connection: $connectable'); // 打印连接性检查结果

        if (connectable &&
            (firstValue + secondValue == 10 ||
                (10 - firstValue) == secondValue)) {
          // 匹配成功，获取连接路径
          // print('Match successful and connectable.'); // 打印匹配成功
          List<Offset> path = getConnectionPath(firstRow, firstCol, row, col);
          // 添加连线，将在同一个 setState 周期内触发绘制
          final currentLine = List<Offset>.from(path); // 创建路径的副本并存储
          lines.add(currentLine);

          // 延迟清除匹配的单元格和连线
          Future.delayed(Duration(milliseconds: 500), () {
            setState(() {
              // print(
              //     'Clearing matched cells: ($firstRow, $firstCol) and ($row, $col)'); // 打印清除单元格
              grid[firstRow][firstCol] = null;
              grid[row][col] = null;
              selectedCells.clear();
              lines.remove(currentLine); // 移除刚刚添加的连线
              score += 10;
              remainingPairs--;

              // 检查游戏是否结束
              if (remainingPairs <= 0) {
                endGame(true);
              }
            });
          });
        } else {
          // 不匹配或无法连接，延迟清除选择
          // print(
          //     'Match failed or not connectable. Clearing selection.'); // 打印匹配失败
          Future.delayed(Duration(milliseconds: 500), () {
            setState(() {
              selectedCells.clear();
            });
          });
        }
      }
    });
  }

  void endGame(bool isWin) {
    timer?.cancel();
    setState(() {
      isGameOver = true;
      if (isWin) {
        // 自动保存训练记录
        int correctCount = requiredPairs - remainingPairs;
        int totalCount = requiredPairs;
        final record = TrainingRecord(
          type: 'make_ten',
          correctCount: correctCount,
          totalCount: totalCount,
          durationMs: Duration(seconds: secondsElapsed).inMilliseconds,
          timestamp: DateTime.now(),
        );
        context.read<TrainingHistoryBloc>().add(TrainingRecordAdded(record));
        print('自动保存凑十训练记录: $correctCount/$totalCount, 用时: ${Duration(seconds: secondsElapsed).inMilliseconds}ms');

        // 显示自动保存提示对话框
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) => AlertDialog(
            title: Text('训练完成!'),
            content: Text('记录已自动保存\n得分: $score\n用时: $secondsElapsed 秒'),
            actions: [
              TextButton(
                child: Text('返回'),
                onPressed: () {
                  Navigator.pop(context);
                  Navigator.pop(context);
                },
              ),
            ],
          ),
        );
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener<TrainingHistoryBloc, TrainingHistoryState>(
      listener: (context, state) {
        if (state is TrainingHistoryLoadedSuccess) {
          startGame();
        }
      },
      child: Scaffold(
      appBar: AppBar(
        title: Text('凑十连连看'),
        actions: [
          IconButton(
            icon: Icon(Icons.refresh),
            onPressed: startGame,
            tooltip: '重新开始',
          ),
        ],
      ),
      body: Column(
        children: [
          // 状态栏
          Container(
            padding: EdgeInsets.all(16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                _buildStatCard(Icons.score, '得分', '$score'),
                _buildStatCard(Icons.timer, '时间', '$secondsElapsed 秒'),
                _buildStatCard(Icons.grid_on, '剩余对数', '$remainingPairs'),
              ],
            ),
          ),

          // 游戏区域
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.orange.shade50,
                  borderRadius: BorderRadius.circular(16),
                  border: Border.all(color: Colors.orange.shade200, width: 2),
                ),
                child: Stack(
                  children: [
                    // 网格
                    GridView.builder(
                      padding: EdgeInsets.all(8),
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: cols,
                        childAspectRatio: 1.0,
                        crossAxisSpacing: 4,
                        mainAxisSpacing: 4,
                      ),
                      itemCount: rows * cols,
                      itemBuilder: (context, index) {
                        final row = index ~/ cols;
                        final col = index % cols;
                        final value = grid[row][col];
                        final isSelected = selectedCells
                            .contains(Offset(col.toDouble(), row.toDouble()));

                        return GestureDetector(
                          onTap: () => selectCell(row, col),
                          child: Container(
                            decoration: BoxDecoration(
                              // 如果单元格为空，则使用背景色，否则根据是否选中显示不同颜色
                              color: value == null
                                  ? Colors.orange.shade50 // 与网格背景色相同，使其看起来为空
                                  : isSelected
                                      ? Colors.orange
                                      : Colors.white,
                              borderRadius: BorderRadius.circular(8),
                              border: value == null
                                  ? null // 空单元格不显示边框
                                  : Border.all(color: Colors.orange.shade300),
                            ),
                            child: Center(
                              child: value != null
                                  ? Text(
                                      '$value',
                                      style: TextStyle(
                                        fontSize: 24,
                                        fontWeight: FontWeight.bold,
                                        color: isSelected
                                            ? Colors.white
                                            : Colors.black87,
                                      ),
                                    )
                                  : null, // 空单元格不显示文本
                            ),
                          ),
                        );
                      },
                    ),

                    // 连线
                    IgnorePointer(
                      child: CustomPaint(
                        size: Size.infinite,
                        painter: LinePainter(lines, cols, rows),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),

          // 底部按钮
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: ElevatedButton(
              onPressed: startGame,
              style: ElevatedButton.styleFrom(
                minimumSize: Size(double.infinity, 50),
              ),
              child: Text('重新开始', style: TextStyle(fontSize: 18)),
            ),
          ),
        ],
      ),
    )
    );
  }

  Widget _buildStatCard(IconData icon, String title, String value) {
    return Card(
      elevation: 4,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      child: Padding(
        padding: const EdgeInsets.all(12.0),
        child: Column(
          children: [
            Icon(icon, color: Colors.deepOrange),
            SizedBox(height: 4),
            Text(title,
                style: TextStyle(fontSize: 12, color: Colors.grey[700])),
            Text(value,
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
          ],
        ),
      ),
    );
  }
}

class LinePainter extends CustomPainter {
  final List<List<Offset>> lines;
  final int cols;
  final int rows;

  LinePainter(this.lines, this.cols, this.rows);

  @override
  void paint(Canvas canvas, Size size) {
    // GridView 的总 padding 是 EdgeInsets.all(16.0) 在父级 Padding
    // GridView 自身的 padding 是 EdgeInsets.all(8)
    // 因此，内容区域相对于 Stack 的偏移是 16 + 8 = 24
    // 但是 LinePainter 是 Stack 的直接子元素，其 size 是 Stack 的大小
    // 我们需要的是 GridView 内部单元格的尺寸和位置

    // GridView 外部 Padding
    final double outerPadding = 16.0;
    // GridView 内部 Padding
    final double innerPadding = 8.0;
    // 总 Padding = 外部 + 内部
    final double totalPadding = outerPadding + innerPadding;

    // GridView 内部单元格之间的间距
    final double crossAxisSpacing = 4.0;
    final double mainAxisSpacing = 4.0;

    // 可用于绘制网格的总宽度和高度 (减去两边的总Padding)
    final double availableWidth = size.width - 2 * totalPadding;
    final double availableHeight = size.height - 2 * totalPadding;

    // 网格中所有间距的总和
    final double totalHorizontalSpacing = (cols - 1) * crossAxisSpacing;
    final double totalVerticalSpacing = (rows - 1) * mainAxisSpacing;

    // 单个单元格的宽度和高度
    final double cellWidth = (availableWidth - totalHorizontalSpacing) / cols;
    final double cellHeight =
        cellWidth; // Ensure square cells due to childAspectRatio: 1.0

    // 绘制的起始偏移量（考虑左边和上边的总Padding）
    final double offsetX = totalPadding;
    final double offsetY = totalPadding;

    final paint = Paint()
      ..color = Colors.deepOrange
      ..strokeWidth = 4
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke;

    for (var line in lines) {
      if (line.length >= 2) {
        // 绘制完整的连线路径
        final path = Path();

        // 移动到起点 (考虑 padding 和 spacing)
        final start = Offset(
          offsetX + line[0].dx * (cellWidth + crossAxisSpacing) + cellWidth / 2,
          offsetY +
              line[0].dy * (cellHeight + mainAxisSpacing) +
              cellHeight / 2,
        );
        path.moveTo(start.dx, start.dy);

        // 添加所有线段
        for (int i = 1; i < line.length; i++) {
          final point = Offset(
            offsetX +
                line[i].dx * (cellWidth + crossAxisSpacing) +
                cellWidth / 2,
            offsetY +
                line[i].dy * (cellHeight + mainAxisSpacing) +
                cellHeight / 2,
          );
          path.lineTo(point.dx, point.dy);
        }

        // 绘制路径
        canvas.drawPath(path, paint);

        // 在拐点处绘制小圆点，增强视觉效果
        final dotPaint = Paint()
          ..color = Colors.deepOrange
          ..style = PaintingStyle.fill;

        for (int i = 0; i < line.length; i++) {
          final point = Offset(
            offsetX +
                line[i].dx * (cellWidth + crossAxisSpacing) +
                cellWidth / 2,
            offsetY +
                line[i].dy * (cellHeight + mainAxisSpacing) +
                cellHeight / 2,
          );
          canvas.drawCircle(point, 4, dotPaint);
        }
      }
    }
  }

  @override
  bool shouldRepaint(LinePainter oldDelegate) {
    return oldDelegate.lines != lines;
  }
}
